﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Billing.Win
{
    [ToolboxItem(true)]
    public partial class ucClientsSearch : Billing.WindowsBase.CustomControls.BaseControl
    {
        private class ListItem
        {
            public string Text { get; set; }
            public object Value { get; set; }
            public override string ToString()
            {
                return Text;
            }

            public ListItem()
                : this(string.Empty, null)
            {

            }

            public ListItem(string Text, object Value)
            {
                this.Text = Text;
                this.Value = Value;
            }

        }

        Billing.DataObjects.BillingDataContext context = new Billing.DataObjects.BillingDataContext();
        System.Data.Linq.ISingleResult<Billing.DataObjects.ClientsView> results = null;

        public System.Data.Linq.ISingleResult<Billing.DataObjects.ClientsView> Results
        {
            get { return results; }
        }

        [Browsable(false)]
        public int? ClientID
        {
            get
            {
                if (string.IsNullOrEmpty(valID.Text))
                    return null;

                int id = 0;
                
                if (int.TryParse(valID.Text, out id))
                    return id;
                return null;
            }
            set
            {
                valID.Text = value == null ? string.Empty : value.ToString();
            }
        }

        private int rowsPerPage = 1000;
        private bool pageingEnabled = true;

        [Browsable(false)]
        public string PhoneNumber
        {
            get
            {
                return valPhoneNumber.Text;
            }
            set
            {
                valPhoneNumber.Text = value;
            }
        }
        public bool PageingEnabled
        {
            get { return pageingEnabled; }
            set
            {
                pageingEnabled = value;
            }
        }

        public int RowsPerPage
        {
            get { return rowsPerPage; }
            set { rowsPerPage = value; }
        }

        private int currentPageNumber = 1;

        public int CurrentPageNumber
        {
            get { return currentPageNumber; }
            set
            {

                currentPageNumber = value;
            }
        }

        private int rowCountInResults;

        public int RowCountInResults
        {
            get { return rowCountInResults; }
            set { rowCountInResults = value; }
        }

        public SearchStatistics SearchStatistics
        {
            get
            {
                return new SearchStatistics(rowCountInResults, rowsPerPage, currentPageNumber);
            }
        }

        public ucClientsSearch()
        {

            InitializeComponent();
            if (!DesignMode)
            {
                valPredefinedDate.SelectedIndex = 0;

                TaxesList.Items.Clear();
                ClientStatusesList.Items.Clear();

                valClientType.Items.Clear();
                valClientType.Items.Add(new ListItem("ნებისმიერი", null));

                foreach (Billing.DataObjects.ClientType item in context.ClientTypes)
                {
                    valClientType.Items.Add(new ListItem(item.Name, item));
                }

                foreach (Billing.DataObjects.Tax item in context.Taxes)
                {
                    TaxesList.Items.Add(new ListItem(item.Name, item), false);
                }

                foreach (Billing.DataObjects.ClientStatuse item in context.ClientStatuses)
                {
                    ClientStatusesList.Items.Add(new ListItem(item.Name, item), false);
                }
            }
        }

        public event EventHandler SearchDone;
        public event EventHandler CancelDone;
        public event EventHandler ClearFieldsDone;

        private void btSearch_Click(object sender, EventArgs e)
        {
            currentPageNumber = 1;
            OnSearch();
        }
        bool IsDateNoFilterSelected = true;

        private void BuildDateInterval()
        {
            valFromDate.Enabled = false;
            valToDate.Enabled = false;
            IsDateNoFilterSelected = false;
            switch (Convert.ToString(valPredefinedDate.SelectedItem.DataValue))
            {
                case "NoFilter":
                    valFromDate.Enabled = false;
                    valToDate.Enabled = false;
                    IsDateNoFilterSelected = true;
                    break;
                case "Today":
                    valFromDate.DateTime = DateTime.Today;
                    valToDate.DateTime = valFromDate.DateTime;
                    break;
                case "Yesterday":
                    valFromDate.DateTime = DateTime.Today.AddDays(-1);
                    valToDate.DateTime = valFromDate.DateTime;
                    break;
                case "ThisWeek":
                    valFromDate.DateTime = GetWeekStartDate();
                    valToDate.DateTime = DateTime.Today;
                    break;
                case "LastWeek":
                    valFromDate.DateTime = GetWeekStartDate().AddDays(-7);
                    valToDate.DateTime = GetWeekStartDate().AddDays(-1);
                    break;
                case "TwoWeeks":
                    valFromDate.DateTime = GetWeekStartDate().AddDays(-14);
                    valToDate.DateTime = GetWeekStartDate().AddDays(-8);
                    break;
                case "ThisMonth":
                    valFromDate.DateTime = GetMonthStartDate();
                    valToDate.DateTime = DateTime.Today;
                    break;
                case "LastMonth":
                    valFromDate.DateTime = GetMonthStartDate().AddMonths(-1);
                    valToDate.DateTime = GetMonthStartDate().AddDays(-1);
                    break;
                case "TwoMonths":
                    valFromDate.DateTime = GetMonthStartDate().AddMonths(-2);
                    valToDate.DateTime = GetMonthStartDate().AddMonths(-1).AddDays(-1);
                    break;
                case "ThisYear":
                    valFromDate.DateTime = GetYearStartDate();
                    valToDate.DateTime = DateTime.Today;
                    break;
                case "LastYear":
                    valFromDate.DateTime = GetYearStartDate().AddYears(-1);
                    valToDate.DateTime = GetYearStartDate().AddDays(-1);
                    break;
                case "TwoYears":
                    valFromDate.DateTime = GetYearStartDate().AddYears(-2);
                    valToDate.DateTime = GetYearStartDate().AddYears(-1).AddDays(-1);
                    break;
                default:
                    valFromDate.Enabled = true;
                    valToDate.Enabled = true;
                    break;
            }
        }

        private DateTime GetYearStartDate()
        {
            return DateTime.Today.AddDays(-DateTime.Today.DayOfYear + 1);
        }

        private DateTime GetMonthStartDate()
        {
            return DateTime.Today.AddDays(-DateTime.Today.Day + 1);
        }

        private DateTime GetWeekStartDate()
        {
            int addDays = 0;
            switch (DateTime.Today.DayOfWeek)
            {
                case DayOfWeek.Friday:
                    addDays = -4;
                    break;
                case DayOfWeek.Monday:
                    addDays = 0;
                    break;
                case DayOfWeek.Saturday:
                    addDays = -5;
                    break;
                case DayOfWeek.Sunday:
                    addDays = -6;
                    break;
                case DayOfWeek.Thursday:
                    addDays = -3;
                    break;
                case DayOfWeek.Tuesday:
                    addDays = -1;
                    break;
                case DayOfWeek.Wednesday:
                    addDays = -2;
                    break;
                default:
                    break;
            }
            return DateTime.Today.AddDays(addDays);
        }

        private string BuildTaxes()
        {
            /*
                0	განუსაზღვრელი
                1	შეიცავს დღგ-ს
                2	არ შეიცავს დღგ-ს
                3	არ იბეგრება
            */
            string s = string.Empty;

            foreach (ListItem item in TaxesList.CheckedItems)
            {
                string value = (item.Value as Billing.DataObjects.Tax).ID.ToString();

                s += string.IsNullOrEmpty(s) ? value : "," + value;
            }

            return s;
        }

        private string BuildStatuses()
        {
            /*  
                1	ახალი
                2	დასრულებული
                3	პასიური
            */
            string s = string.Empty;

            foreach (ListItem item in ClientStatusesList.CheckedItems)
            {
                string value = (item.Value as Billing.DataObjects.ClientStatuse).ID.ToString();

                s += string.IsNullOrEmpty(s) ? value : "," + value;
            }

            return s;
        }

        private string BuildClientTypes()
        {
            if (valClientType.SelectedItem == null)
                return string.Empty;
            ListItem item = valClientType.SelectedItem.DataValue as ListItem;
            if (item.Value == null)
                return string.Empty;
            return (item.Value as Billing.DataObjects.ClientType).ID.ToString();
        }

        private void valPredefinedDate_SelectionChanged(object sender, EventArgs e)
        {
            BuildDateInterval();
        }

        private void btRetry_Click(object sender, EventArgs e)
        {
            CleareFields();
            if (ClearFieldsDone != null)
                ClearFieldsDone(this, EventArgs.Empty);
        }

        public void Clear()
        {
            CleareFields();
        }

        private void CleareFields()
        {
            this.valID.Text = string.Empty;
            this.valBudgeted.CheckState = CheckState.Indeterminate;
            this.valName.Text = string.Empty;
            this.valIdentificationNumber.Text = string.Empty;
            this.TaxesList.ClearSelected();
            this.ClientStatusesList.ClearSelected();
            this.valPredefinedDate.SelectedIndex = 0;
            this.chbContractInterval.Checked = false;
            this.valContractNumber.Text = string.Empty;
            this.valContractToDate.Value = null;
            this.valFromDate.Value = null;
            this.valDate.Value = null;
            this.valPhoneNumber.Text = string.Empty;
            BuildDateInterval();
        }

        private void btCancel_Click(object sender, EventArgs e)
        {
            if (CancelDone != null)
                CancelDone(this, EventArgs.Empty);
        }

        private void OnSearch()
        {
            if (DesignMode)
                return;

            int id = 0;
            int.TryParse(valID.Text, out id);
            string identificationNumber = valIdentificationNumber.Text;
            string name = valName.Text;
            string clientTypes = BuildClientTypes();
            string statuses = BuildStatuses();
            string taxes = BuildTaxes();
            BuildDateInterval();
            DateTime? fromDate = !IsDateNoFilterSelected ? valFromDate.DateTime : (DateTime?)null;
            DateTime? toDate = !IsDateNoFilterSelected ? valToDate.DateTime : (DateTime?)null;
            string contractNumber = valContractNumber.Text.Trim();
            DateTime? contractFromDate = valContractFromDate.Enabled ? valContractFromDate.DateTime : (DateTime?)null;
            DateTime? contractToDate = valContractToDate.Enabled ? valContractToDate.DateTime : (DateTime?)null;
            string phoneNumbers = valPhoneNumber.Text;
            DateTime? date = (valDate.ButtonsLeft["Selected"] as Infragistics.Win.UltraWinEditors.StateEditorButton).Checked ? valDate.DateTime : (DateTime?)null;

            string rentalStatuses = string.Empty;
            decimal? minBalance = null;
            decimal? maxBalance = null;

            //decimal? minBalance = valMinBalance.Value == null || valMinBalance.Value == Convert.DBNull ? (decimal?)null : Convert.ToDecimal(valMinBalance.Value);
            //decimal? maxBalance = valMaxBalance.Value == null || valMaxBalance.Value == Convert.DBNull ? (decimal?)null : Convert.ToDecimal(valMaxBalance.Value);


            if (this.results != null)
                this.results.Dispose();
            this.results = null;
            int? rowsFound = null;
            bool? budgeted = null;
            switch (valBudgeted.CheckState)
            {
                case CheckState.Checked:
                    budgeted = true;
                    break;
                case CheckState.Unchecked:
                    budgeted = false;
                    break;
                default:
                    budgeted = null;
                    break;
            }

            context = new Billing.DataObjects.BillingDataContext();
            this.results = context.ClientsSelect(id, clientTypes, identificationNumber, name, statuses, taxes, fromDate, toDate, contractFromDate, contractToDate, contractNumber, phoneNumbers, date, rentalStatuses, minBalance, maxBalance,
                (pageingEnabled) ? rowsPerPage : 0,
                (pageingEnabled) ? currentPageNumber : 0,
                null,
                budgeted,
                ref rowsFound);

            this.rowCountInResults = rowsFound.Value;

            if (SearchDone != null)
                SearchDone(this, EventArgs.Empty);
        }

        public void Search()
        {
            OnSearch();
        }

        private void chbContractInterval_CheckedChanged(object sender, EventArgs e)
        {
            valContractFromDate.Enabled = chbContractInterval.Checked;
            valContractToDate.Enabled = valContractFromDate.Enabled;
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Enter)
            {
                //if (e.Control)
                //    btRetry_Click(btRetry, EventArgs.Empty);
                //else
                btSearch_Click(btSearch, EventArgs.Empty);
                return true;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

    }
}
